home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 16
/
Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso
/
Aminet
/
misc
/
emu
/
QDOS2.lha
/
QLsource
/
ROMsrc
/
SYS
/
PROCESSOR_asm
< prev
next >
Wrap
Text File
|
1995-09-04
|
9KB
|
421 lines
*/beginfile PROCESSOR_asm
; --------------------------------------------------------------
; PROCESSOR_asm - QDOS processor specific routines
; - last modified 04/08/95
; QDOS-Amiga sources by Rainer Kowallik
; ...latest changes by Mark J Swift
; ...68040/68060 changes by SNG, 16/8/94
; --------------------------------------------------------------
;*/beginoverlay
; -------------------------------------------------------------
; check attn flags for 68000/008 processor. Returns Z if so
CHK6800X:
movem.l d1/a6,-(a7)
bsr GET_ATTN
btst #0,d1
movem.l (a7)+,d1/a6
rts
; -------------------------------------------------------------
; set attn flags for processor.
SET_ATTN:
movem.l d0/a6,-(a7)
move.l a7,d1 ; Calculate start of
andi.w #-$8000,d1 ; system variables
move.l d1,a6
bsr ATTN_FLGS
move.w d0,d1
move.w d1,SV_IDENT+2(a6) ; set attn flags
movem.l (a7)+,d0/a6
rts
; -------------------------------------------------------------
; get attn flags for processor.
GET_ATTN:
movem.l d0/a6,-(a7)
move.l a7,d1 ; Calculate start of
andi.w #-$8000,d1 ; system variables
move.l d1,a6
move.w SV_IDENT+2(a6),d1 ; get attn flags
movem.l (a7)+,d0/a6
rts
; -------------------------------------------------------------
; create attention flags (check processor type)
; bit 0 - at least 68010
; bit 1 - at least 68020
; bit 2 - at least 68030
; bit 3 - at least 68040
; bit 4 - at least 68881 (possibly 68882)
; bit 5 - 68882 present (or emulation)
; bit 6 - 68040 or 68060 on-chip FPU enabled
; bit 7 - at least 68060
;
; Note: If the MC68060 FPU has been turned off in software since
; the last reset (which enables it) bit 6 is zero, as if the FPU
; was not present and we were using an EC or LC processor.
;
ATTN_FLGS:
movem.l d1/a0-a3,-(a7)
dc.w $2078,$0010 ; move.l $10.w,a0
dc.w $2478,$002C ; move.l $2C.w,a2
lea LF80C18(pc),a1
dc.w $21C9,$0010 ; move.l a1,$10.w
; (ILLEGAL INSTRUCTION vector)
dc.w $21C9,$002C ; move.l a1,$2C.w
; (F-LINE EMULATION vector)
move.l a7,a1
moveq #$0,d0 ; initialise attn flags
move.b #0,161(a6) ; ditto for QDOS
dc.w $4E7B,$0801 ; movec d0,vbr
bset #$0,d0 ; vbr present - 68010 at least
; Clear Data cache
; | Freeze Data cache
; | |Enable Data cache (off)
; | || Clear Instruction cache
; | || | Enable Instruction cache
; | || | |
move.l #%0000101000001001,d1
dc.w $4E7B,$1002 ; movec d1,cacr
dc.w $4E7A,$1002 ; movec cacr,d1
bset #$1,d0 ; cacr present - 68020 at least
move.b #$20,161(a6) ; store for QDOS
btst #$9,d1
beq.s LF80BB4 ; no data cache - not a 68030
bset #$2,d0 ; definitely a 68030
move.b #$30,161(a6) ; store for QDOS
LF80BB4:
btst #$0,d1
bne.s LF80BDC ; cacr present and (EI) bit
; operative - not a 68040
or.w #$C,d0 ; 68040 at least!
move.b #$40,161(a6) ; store for QDOS
dc.w $F4D8 ; CINVA ic/dc - inavalidate caches
;
; This code set up the TTR/ACU registers to stop data cacheing of memory
; in the first 16 Mb. This is not needed under Amiga Qdos as the cache is
; explicitly cleared when necessary after DMA,
;
; SNG move.l #$C040,d1 ; Serialize 0-16 Mb
; moved: dc.w $4E7B,$1006 ; movec d1,(006)
moveq #0,d1 ; MMU off
dc.w $4E7B,$1003 ; movec d1,TCR
move.l #$FFC000,d1 ; ACU/TTU off
dc.w $4E7B,$1007 ; movec d1,(007)
dc.w $4E7B,$1004 ; movec d1,(004)
dc.w $4E7B,$1005 ; movec d1,(005)
dc.w $4E7B,$1006 ; movec d1,(006) - moved by SNG
move.l #$80008000,d1 ; Both caches on, for 040+
bra.s SetCACR
LF80BDC:
; Enable Instruction cache >=040 (1=ON)
; | Write Allocation (1=ON)
; | | Clear Data cache
; | | | Enable Data cache (1=ON)
; | | | | Clear Instruction cache
; | | | | | Enable Instruction cache
; | | | | | |
move.l #%1010100100001001,d1
SetCACR dc.w $4E7B,$1002 ; movec d1,cacr
btst #$3,d0
beq.s LF80BF6 ; skip if not a 68040 or later
;
; 68060 initialisation added here
;
; Note this tests the new PCR register to find out if we're on
; an 060. If this fails, the routine returns after checking for
; a 68040 FPU. Otherwise it turns on the 060 accelerators and
; reports the presence of an enabled FPU, if it finds one.
;
lea NoPCR(pc),a3 ; Continuation if PCR absent
dc.w $21CB,$0010 ; move.l a3,$10.w
; (ILLEGAL INSTRUCTION vector)
dc.w $4E7A,$1808 ; 68060 PCR to D1 or illegal
swap d1
cmp.w #$0431,d1
beq.s No60FPU ; No FPU!
; cmp.w #$0430,d1 ; The only other possibility
; bne.s Unknown ; at the time of writing...
btst #17,d1 ; Test swapped DFP flag bit
bne.s No60FPU ; If FPU is disabled, leave off
bset #6,d0 ; Note 68060 FPU is available
No60FPU bset #7,d0 ; Set 060 bit in ATTN flags
move.b #$60,161(a6) ; Tell Qdos we're on an 060
swap d1
bset #0,d1 ; Ensure SOEP is on
dc.w $4E7B,$1808 ; Store updated PCR
;
; Enable store buffer, code, data and (cleared) branch cache
;
move.l #$A0C08000,d1 ; EDC+ESB+EBC+CABC+EIC
dc.w $4E7B,$1002 ; movec d1,cacr
bra.s LF80C18
;
; The old code to check for the 040 FPU always failed because the
; 68040 does not support cpSAVE and cpRESTORE! Substitute FNOP
;
; dc.w $F327 ; cpSAVE
; dc.w $F35F ; cpRESTORE
TryFPU dc.w $F280,0 ; FNOP sifts out ECs and LCs
bset #$6,d0 ; 68040 FPU present
bra.s LF80C18
NoPCR movea.l a1,a7 ; Tidy stacked exception frame
bra.s TryFPU
;
; Test for an off-CPU co-processor
;
LF80BF6:
moveq #$0,d1
dc.w $F201,$9000 ; FMOVE D1 to FPU
dc.w $F201,$B000 ; FMOVE FPU to D1
tst.l d1 ; A most unlikely case
bne.s LF80C18 ; Something strange has happened
bset #$4,d0 ; 68881 at least
dc.w $F327 ; cpSAVE -(A7)
cmpi.b #$18,$1(a7) ; Check for 68882 frame
beq.s LF80C16
bset #$5,d0 ; 68882 at least
LF80C16:
dc.w $F35F ; cpRESTORE (A7)+
LF80C18:
move.l a1,a7 ; clean-up stack
dc.w $21C8,$0010 ; move.l a0,$10.w
dc.w $21CA,$002C ; move.l a2,$2C.w
movem.l (a7)+,d1/a0-a3
rts
; -------------------------------------------------------------
; clear data and instruction caches
CLRALL:
movem.l d0-d1/d4,-(a7)
move.l #$808,d1
bra.s L0000C3E
; -------------------------------------------------------------
; clear data caches
CLRDATA:
movem.l d0-d1/d4,-(a7)
moveq #$8,d1
rol.l #8,d1
; -------------------------------------------------------------
; clear cache(s). d1=$800 - clear data cache
; d1=$808 - clear data and instruction caches
; and on 68040/060 - update memory from caches
L0000C3E:
move.w sr,-(a7)
ori.w #$0700,sr ; interrupts off
exg d1,d4
bsr GET_ATTN
exg d1,d4
btst #$1,d4 ; branch if '020 or more
bne.s L0000C48
ifd ShoCach
move.l d7,-(a7)
move.w #$8000,d7
WAITBLU:
move.w #$000F,$DFF180
move.w #0,$DFF180
dbra d7,WAITBLU
move.l (a7)+,d7
endif
bra.s CLRCACHEX ; ...otherwise exit
L0000C48:
btst #$3,d4
bne.s L0000C68 ; '040 ?
;
; No explicit test for the 060 is needed as long as the 040
; bit remains set by tests on a 68060.
;
; btst #$7,d4 ; Check for '060
; bne.s L0000C68
and.l #$808,d1
ori #$700,sr
dc.w $4E7A,$0002 ; movec cacr,d0
or.l d1,d0
dc.w $4E7B,$0002 ; movec d0,cacr
ifd ShoCach
move.l d7,-(a7)
move.w #$8000,d7
WAITRED:
move.w #$0F00,$DFF180
move.w #0,$DFF180
dbra d7,WAITRED
move.l (a7)+,d7
endif
bra.s CLRCACHEX
L0000C68:
btst #$3,d1
bne.s L0000C74
dc.w $F478 ; CPUSHA dc ('040 only)
; update memory from cache
bra.s L0000C76
L0000C74:
dc.w $F4F8 ; CPUSHA ic/dc ('040 only)
; update memory from caches
L0000C76:
ifd ShoCach
move.l d7,-(a7)
move.w #$8000,d7
WAITGRN:
move.w #$00F0,$DFF180
move.w #0,$DFF180
dbra d7,WAITGRN
move.l (a7)+,d7
endif
CLRCACHEX:
move.w (a7)+,sr
movem.l (a7)+,d0-d1/d4
tst.l d0
rts
; -------------------------------------------------------------
; set bits in cacr d0=bits to set d1=bits to clear/alter
; This assumes 030 control register bits and tries to rework
; them for the 040. It fails, and won't suit 060 either. Luckily
; Mark says it is not used or needed in current Qdos versions.
ifne 0 ; Ignore this code block
L0000C8E:
movem.l d2-d4,-(a7)
moveq #$0,d3
exg d1,d4
bsr GET_ATTN
exg d1,d4
btst #$1,d4 ; exit if not at least '020
beq.s L0000CAE
and.l d1,d0
or.w #$808,d0 ; signal always clear caches
not.l d1
L0000CB6:
ori #$700,sr ; DODGY? Not restored later
dc.w $4E7A,$2002 ; movec cacr,d2
btst #$3,d4
beq.s L0000CD0 ; skip if not '040
;
; Attempts to convert 040 CACR to 030 form;
;
move.l d2,d3
andi.l #$7FFF0000,d3 ; keep '060 bits...
; mimick ED & EI
swap d2 ; 8000 8000
ror.w #8,d2 ; 8000 0080
rol.l #1,d2 ; 0000 0101
andi.w #$0101,d2 ; ...only relevant bits
move.w d2,d3 ; mimick DBE & IBE
rol.w #4,d3 ; 0000 1010
or.l d3,d2 ; 0000 1111
L0000CD0:
move.l d2,d3 ; cache register to d3
and.l d1,d2 ; mask off changed bits
or.l d0,d2 ; or in set bits
btst #$3,d4
beq.s L0000CEC ; skip if not '040
; 0000 0101
ror.l #1,d2 ; 8000 0080
rol.w #8,d2 ; 8000 8000
and.l #$80008000,d2 ;
swap d3
or.w d3,d2 ; keep '060 bits...
swap d3
swap d2 ; 8000 8000
nop
dc.w $F4F8 ; CPUSHA ic/dc ('040 only)
; update memory from caches
L0000CEC:
nop
dc.w $4E7B,$2002 ; movec d2,cacr
nop
L0000CAE:
move.l d3,d0 ; return old bits in d0
movem.l (a7)+,d2-d4
rts
endif ; End of commented out lump
;*/endoverlay
; --------------------------------------------------------------
;*/endfile